#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jansson.h>
#include "memory.h"
#include "cfg.h"


ptr_cfglst load_configs(const char *filename)
{
    json_t *config;
    json_error_t error;
    config = json_load_file(filename, 0, &error);

    const char *key;
    json_t *value;
    ptr_cfglst cfglst = cfglst_init();

    json_object_foreach(config, key, value) {
        char *pattern = (char *) xmalloc(sizeof(char) * (strlen(key) + 1));
        strcpy(pattern, key);
        size_t dest_depth;
        char **dest = split_dest_path((json_string_value(value)),
                                      "->", &dest_depth);
        cfglst_append(&cfglst, pattern, dest, dest_depth);
    }
    json_decref(config);
    return cfglst;
}

size_t get_dest_depth(const char *dest, const char *separator)
{
    size_t counter = 0;
    for (; (*dest != '\0') && (dest = strstr(dest, separator)); dest++) {
        counter++;
    }
    return counter;
}

ptr_cfglst get_matched_rule(ptr_cfglst config, const char *name)
{
    cfglst_foreach(config) {
        if (re_matched(name, config->pattern)) {
            return config;
        }
    }
    return NULL;
}

char **split_dest_path(const char *dest, char *separator, size_t *dest_depth)
{
    char *dest_cp = (char *) xmalloc(sizeof(char) * (strlen(dest) + 1));
    strcpy(dest_cp, dest);
    *dest_depth = get_dest_depth(dest_cp, separator);
    char **out = (char **) xmalloc(sizeof (char *) * (*dest_depth));

    char *result = NULL;
    size_t depth = 0;
    for (result = strtok(dest_cp, separator);
         result != NULL;
         result = strtok(NULL, separator))
    {
        out[depth] = (char *) xmalloc(strlen(result) + 1);
        strcpy(out[depth], result);
        depth++;
    }
    free(dest_cp);
    return out;
}

void free_configs(ptr_cfglst cfglst)
{
    ptr_cfglst tmp = cfglst;
    for (; (tmp) != NULL; (tmp) = (tmp)->next) {
        free(tmp->pattern);
        for (size_t depth = 0; depth < (tmp->dest_depth); depth++) {
            free(tmp->dest[depth]);
        }
        free(tmp->dest);
    }
    cfglst_free(cfglst);
}
